package com.jf.json;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;


/**
 * Created with IntelliJ IDEA
 * Description:Java对象和JSON对象的转换
 * User:22954
 * Date:2024-09-10
 * Time:23:19
 */
public class JavaJson {
    /*
    Java对象和JSON对象转换需导入gson.jar包
    转换流程:
        1.实例化一个Gson对象 Gson gson = new Gson()
        2.Java转JSON
            public String toJson(Object src)
            1'Object-普通对象 -> Json对象  属性名->key 值->value
            2'Object-List<E> -> 数组  E为对象时,数组为Json对象数组
            3'Object-Map<E>  -> Json对象  key为Map的key(数字自动转成字符串),value为Map的value
        3.JSON转Java
            A public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException
            B public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException
            1'转成普通对象 用方法A,传Json字符串和需转换成的类的class类
            2'转成List/Map 用方法B,传Json字符串和Type对象
                Type type = new TypeToken<T>() {}.getType(); T为List<E>/Map<K,V>
    细节:
        1.JSON转Java时,若转成的类为泛型类(不为List/Map),可直接传Class类而不用去获取Type,但是不严谨
        2.JSON转Java时,转成的Map的key值不能是对象,只能是字符串或数字
        3.JSON转Java时,泛型类使用 Type type = new TypeToken<T>() {}.getType() 解释:
            所有类的泛型在编译时会因擦除机制而转成Object(改变的是类结构,实际运行仍是指定类,且有字节码记录)
            因此在运行过程中,不能直接获得指定的泛型类型
            {} 为匿名内部类的表示方式
            匿名内部类继承外部类,因为子类对父类的继承有确定性,在内部类的泛型已经转换为具体类型,编码时也为具体类型,不会丢失
     */
    public static void main(String[] args) {
        Gson gson = new Gson();

        Book book = new Book(1, "三国演义");
        System.out.println(book);
        String bookJson = gson.toJson(book);
        System.out.println(bookJson);

        Book book2 = gson.fromJson(bookJson, Book.class);
        System.out.println(book2);

        ArrayList<Book> bookList = new ArrayList<>();
        bookList.add(new Book(1, "三国演义"));
        bookList.add(new Book(2, "水浒传"));
        bookList.add(new Book(3, "西游记"));

        String bookListJson = gson.toJson(bookList);
        System.out.println(bookListJson);

        Type type = new TypeToken<ArrayList<Book>>() {
        }.getType();
        ArrayList<Book> books = gson.fromJson(bookListJson, type);
        System.out.println(books);

        HashMap<Integer, Book> bookMap = new HashMap<>();
        bookMap.put(1, new Book(1, "三国演义"));
        bookMap.put(2, new Book(2, "水浒传"));
        System.out.println(bookMap);

        String bookMapJson = gson.toJson(bookMap);
        System.out.println(bookMapJson);
        type = new TypeToken<HashMap<Integer, Book>>() {
        }.getType();
        HashMap<Integer, Book> books_ = gson.fromJson(bookMapJson, type);
        System.out.println(books_);
    }
}
